<?php

namespace App\Http\Controllers\V1\Permission;

use App\Http\Requests\V1\RoleRequest;
use App\Models\V1\Menus;
use App\Models\V1\Permission;
use App\Models\V1\Role;
use App\Models\V1\Submenus;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Log;
use Auth;

class RolesController extends Controller
{
    //
    /**
     * 显示角色列表页面
     *
     * @return \Illuminate\Http\Response
     */
    public function index() {
        return view('v1.permission.roles');
    }

    /**
     * 获取角色数据
     *
     * @param Request $request
     */
    public function postIndex(Request $request)
    {
        $response = [
            'code' => 1,
            'msg' => '',
            'count' => 0,
            'data' => [],
        ];

        // 获取符合查询条件的角色数据
        $currentPage = $request->get('page');
        $rows = $request->get('limit');
        $keywords = $request->get('keywords');

        // 获取符合查询条件的角色数据
        $data = $this->getRoleList($currentPage, $rows, $keywords);

        if (!$data->isEmpty()) {

            $formatList = array();

            $count = $data->total() > 0 ? $data->total() : 0;

            if ($count > 0) {
                // 格式化数据
                foreach ($data->items() as $item) {
                    $formatItem['display_name'] = $item['display_name'];
                    $formatItem['name'] = $item['name'];
                    $formatItem['description'] = $item['description'];
                    $formatItem['updated_at'] = $item['updated_at']->format('Y-m-d H:i:s');
                    $formatItem['created_at'] = $item['created_at']->format('Y-m-d H:i:s');
                    array_push($formatList, $formatItem);
                }

                $response['code'] = 0;
                $response['msg'] = '加载数据成功';
                $response['count'] = $count;
                $response['data'] = $formatList;
            }
        }
        return $response;
    }

    /***
     * 进入编辑或新增界面
     * @param Request $request
     * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
     */
    public function showView(Request $request){
        $view = $request->input('view');
        $data['view'] = $view;
        $all_permissions = Submenus::where('url','!=','')->pluck('slug')->toArray();
        $data['all_permissions'] = $all_permissions;
        switch ($view) {
            case 'addData':
                return view('v1.permission.roles_item', $data);
                break;
            case 'editData':
                $data['name'] = $request->input('name');
                $role = $this->getRoleByCode($data['name']);
                $data['itemData'] = $role;
                //角色拥有的权限
                $role_permissions = $role->permissions->pluck('name')->toArray();
                //所有权限
                $data['role_permissions'] = $role_permissions;
                Log::info('$data',$data);
                return view('v1.permission.roles_item', $data);
                break;
        }
    }

    /**
     * 显示角色数据导入页面
     *
     * @param Request $request
     * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
     */
    public function importView(Request $request)
    {
        // 获取登录用户
        $loginUser = Auth::user();

        $data['view'] = $request->input('view');
        $data['code'] = $loginUser['code'];

        return view('v1.form.upload_excel', $data);
    }


    /**
     * 删除角色基本信息
     *
     * @param RoleRequest $request
     * @return array
     */
    public function deleteData(RoleRequest $request)
    {
        $response = [
            'rspStatus' => false,
            'rspMsg' => '角色代码[' . $request->input('name') . '],删除失败！',
        ];

        if ($request->method() === 'POST') {
            // 验证请求
            $this->validateRole($request);
            $name = $request->input('name');
            if ($name === 'admin') {
                $response['rspMsg']= '不可以删除管理员';
                return $response;
            }

            // 删除角色信息
            $successFlag = $this->handleDelete($request, false);

            if ($successFlag) {
                $response['rspStatus'] = true;
                $response['rspMsg'] = '角色代码[' . $request->input('name') . '],删除成功！';
            }
        }

        return $response;
    }

    /**
     * 批量删除角色基本信息
     *
     * @param Request $request
     * @return array
     */
    public function deleteBatchData(Request $request)
    {
        $response = [
            'rspStatus' => false,
            'rspMsg' => '角色批量删除失败！',
        ];

        if ($request->method() === 'POST') {
            // 删除学期信息
            $successFlag = $this->handleDelete($request, true);

            if ($successFlag) {
                $response['rspStatus'] = true;
                $response['rspMsg'] = '角色批量删除成功！';
            }
        }

        return $response;
    }

    /**
     * 编辑角色基本信息
     *
     * @param Request $request
     * @return array
     */
    public function updateData(Request $request)
    {
        $response = [
            'rspStatus' => false,
            'rspMsg' => '角色更新失败！',
        ];

        if ($request->method() === 'POST') {
            // 删除学期信息
            $successFlag = $this->handleUpdate($request);

            if ($successFlag) {
                $response['rspStatus'] = true;
                $response['rspMsg'] = '角色更新成功！';
            }
        }

        return $response;
    }


    /**
     * 新增角色信息
     * @param Request $request
     * @return array
     */
    public function addData(Request $request)
    {
        $response = [
            'rspStatus' => false,
            'rspMsg' => '角色新增失败！',
        ];

        if ($request->method() === 'POST') {
            $successFlag = $this->handleAdd($request);
            if ($successFlag) {
                $response['rspStatus'] = true;
                $response['rspMsg'] = '角色新增成功！';
            }
        }
        return $response;
    }


    ///////////////////////////////////////////////////////////////////
    /// 验证表单功能函数
    ///////////////////////////////////////////////////////////////////
    /**
     * 处理新增、更新角色信息验证请求
     *
     * @param RoleRequest $request
     */
    private function validateRole(RoleRequest $request)
    {
        $rules = $request->rules();
        if ($request->input("captcha") !== null) {
            $rules['captcha'] = 'bail|required|captcha';
        }
        $messages = $request->messages();
        // 执行表单数据验证
        $this->validate($request, $rules, $messages);
    }

    ///////////////////////////////////////////////////////////////////
    /// 获取数据功能函数
    ///////////////////////////////////////////////////////////////////
    /**
     * 分页查询符合条件的角色列表数据
     *
     * @param int $page 当前页数
     * @param $rows 每页显示条数
     * @param $keywords 搜索关键词
     * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator 分页对象
     */

    private function getRoleList($page = 1, $rows, $keywords) {
        if (!isset($keywords) || empty($keywords)) {
            $data = Role::orderBy('id', 'asc')->paginate($rows, ['*'], 'page', $page);
        } else {
            $data = Role::where('display_name', 'like', '%' . $keywords . '%')->orderBy('id', 'asc')
                ->paginate($rows, ['*'], 'page', $page);
        }
        return $data;
    }


    /**
     * 根据角色代码获取对应角色信息
     *
     * @param $code
     * @return \Illuminate\Database\Eloquent\Model|null|static
     */
    private function getRoleByCode($code)
    {
        $role = Role::where('name', $code)->first();
        return $role;
    }

    /**
     * 根据权限代码获取对应权限信息
     *
     * @param $code
     * @return \Illuminate\Database\Eloquent\Model|null|static
     */
    private function getPermissionByCode($code)
    {
        $permission = Permission::where('name', $code)->first();
        return $permission;
    }

    
    /**
     * 处理删除角色信息
     *
     * @param Request $request
     * @param bool $bBatch 是否为批量数据
     * @return bool
     */
    private function handleDelete(Request $request, $bBatch)
    {
        $where = $request->input('name');

        if ($bBatch) { // 批量删除
            foreach ($where as $code) {
                $rspObj = Role::where('name', $code)
                    ->where(function ($query){
                        $query->where('name','<>','admin');
                    })->delete();
            }
        } else { // 单条删除
            $rspObj = Role::where('name', $where)
                ->where(function ($query){
                    $query->where('name','<>','admin');
                })->delete();
        }

        return $rspObj;
    }

    /**
     * 更新角色信息
     *
     *
     * @param Request $request
     * @param bool $bBatch 是否为批量数据
     * @return bool
     */
    private function handleUpdate(Request $request)
    {
        $where = $request->input('name');
        $role = $this->getRoleByCode($where);
        //1.更新权限
        $all_permissions = Permission::all()->pluck('name');
        foreach ($all_permissions as $item) {
            $value = $request->input($item);
            $permission = $this->getPermissionByCode($item);
            if ($value === 'on' && !$role->hasPermission($item)) {
                $role -> attachPermission($permission);
            }else if ($value !== 'on' && $role->hasPermission($item)){
                $role -> detachPermission($permission);
            }else{
            }
        }
        //2.根据当前角色权限判断是否要选父权限
        //当前角色的权限
        $role_names = $role->permissions->pluck('name')->toArray();
        foreach ($role_names as $role_name) {
            //当前菜单
            $current_menu = Submenus::where('slug', $role_name)->first();
            $this->attachParentMenuPermission($role, $current_menu);
        }
        $updateData = [
            'display_name' => $request->input('display_name'),
            'description' => $request->input('description'),
        ];
        $rspObj = Role::where('name', $where)->update($updateData);
        return $rspObj;
    }

    /**
     * 新增角色信息
     * @param Request $request
     * @return bool
     */
    private function handleAdd(Request $request)
    {
        $display_name = $request->input('display_name');
        $description = $request->input('description');

        //1.创建角色
        $role = new Role();
        $role->name = 'role'.uniqid();
        $role->display_name = $display_name;
        $role->description = $description;
        $role->save();
        //1.为角色分配权限
        $all_permissions = Permission::all()->pluck('name');
        foreach ($all_permissions as $item) {
            $value = $request->input($item);
            $permission = $this->getPermissionByCode($item);
            if ($value === 'on' && !$role->hasPermission($item)) {
                $role -> attachPermission($permission);
            }else if ($value !== 'on' && $role->hasPermission($item)){
                $role -> detachPermission($permission);
            }else{
            }
        }
        //2.根据当前角色权限判断是否要选父权限
        //当前角色的权限
        $role_names = $role->permissions->pluck('name')->toArray();
        foreach ($role_names as $role_name) {
            //当前菜单
            $current_menu = Submenus::where('slug', $role_name)->first();
            $this->attachParentMenuPermission($role, $current_menu);
        }
        return true;
    }


    /**
     * 根据子菜单，分配父菜单权限
     * @param $role
     * @param $menu
     */
    private function attachParentMenuPermission($role, $menu)
    {
        $parent_code = $menu->parent_code;
        $menu_permission = $this->getPermissionByCode($menu['slug']);
        if (!$role->hasPermission($menu['slug'])) {
            $role -> attachPermission($menu_permission);
        }
        //说明是
        if ($parent_code === '0') {
            $menu_code = $menu->menu_code;
            $menu = Menus::where('code',$menu_code)->first();
            $menu_permission = $this->getPermissionByCode($menu['slug']);
            if (!$role->hasPermission($menu['slug'])) {
                $role->attachPermission($menu_permission);
            }
        }else{
            //根据子菜单，获取父菜单
            $current_menu = Submenus::where('code',$parent_code)->first();
            $this->attachParentMenuPermission($role,$current_menu);
        }
    }

}
